{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b309b4de-0009-4d61-a4f1-d52db9caa155",
   "metadata": {},
   "source": [
    "# 常用计算示例\n",
    "\n",
    "原文: https://www.jianshu.com/p/339c91ae9f41\n",
    "\n",
    "## 一、 常用内置符号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "bea8dbd9-aecc-47dd-85b0-56b4f479130d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sympy.I --> I\n",
      "sympy.I ** 2 --> -1\n",
      "sympy.sqrt(-1) --> I\n",
      "\n",
      "sympy.E --> E\n",
      "sympy.log(sympy.E) --> 1\n",
      "\n",
      "1/sympy.oo --> 0\n",
      "1 + sympy.oo --> oo\n",
      "\n",
      "sympy.pi --> pi\n",
      "sympy.sin(sympi.pi/2) --> 1\n"
     ]
    }
   ],
   "source": [
    "import sympy\n",
    "\n",
    "# 虚数单位i\n",
    "print('sympy.I -->', sympy.I)\n",
    "print('sympy.I ** 2 -->', sympy.I ** 2)\n",
    "print('sympy.sqrt(-1) -->', sympy.sqrt(-1))\n",
    "\n",
    "# 自然对数底e\n",
    "print()\n",
    "print('sympy.E -->', sympy.E)\n",
    "print('sympy.log(sympy.E) -->', sympy.log(sympy.E))\n",
    "\n",
    "# 无穷大\n",
    "print()\n",
    "print('1/sympy.oo -->', 1/sympy.oo)\n",
    "print('1 + sympy.oo -->', 1+sympy.oo)\n",
    "\n",
    "# 圆周率pi\n",
    "print()\n",
    "print('sympy.pi -->', sympy.pi)\n",
    "print('sympy.sin(sympi.pi/2) -->', sympy.sin(sympy.pi/2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e161421e-398d-460e-ad0c-f9ef87224840",
   "metadata": {},
   "source": [
    "## 二、初等运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "327b9d97-cfa1-4683-802b-9f36b97029ae",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sympy.log(sympy.E) --> 1\n",
      "sympy.log(sympy.E ** 3) --> 3\n",
      "sympy.log(1000, 10) --> 3\n",
      "\n",
      "sympy.sqrt(4)--> 2\n",
      "sympy.sqrt(-1)--> I\n",
      "\n",
      "sympy.root(8, 3)--> 2\n",
      "\n",
      "sympy.factorial(4)--> 24\n",
      "\n",
      "sympy.sin(sympy.pi)--> 0\n",
      "sympy.sin(sympy.pi/2)--> 1\n"
     ]
    }
   ],
   "source": [
    "# 求对数\n",
    "print('sympy.log(sympy.E) -->', sympy.log(sympy.E))\n",
    "print('sympy.log(sympy.E ** 3) -->', sympy.log(sympy.E ** 3))\n",
    "print('sympy.log(1000, 10) -->', sympy.log(1000, 10))\n",
    "\n",
    "# 求平方根\n",
    "print()\n",
    "print('sympy.sqrt(4)-->', sympy.sqrt(4))\n",
    "print('sympy.sqrt(-1)-->', sympy.sqrt(-1))\n",
    "\n",
    "# 求n次方根\n",
    "print()\n",
    "print('sympy.root(8, 3)-->', sympy.root(8, 3))\n",
    "\n",
    "# 求阶乘\n",
    "print()\n",
    "print('sympy.factorial(4)-->', sympy.factorial(4))\n",
    "\n",
    "# 求三角函数\n",
    "print()\n",
    "print('sympy.sin(sympy.pi)-->', sympy.sin(sympy.pi))\n",
    "print('sympy.sin(sympy.pi/2)-->', sympy.sin(sympy.pi/2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56c9ca57-4eae-4ea1-aa10-218ddb2c0b33",
   "metadata": {},
   "source": [
    "## 三、表达式与表达式求值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "b1e1feda-2c53-4a98-9162-bd21e945270b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "type(fx)--> <class 'sympy.core.add.Add'>\n",
      "fx.evalf(subs={x:2})--> 5.00000000000000\n",
      "f.evalf(subs={x:1,y:2})--> 4.00000000000000\n",
      "f.evalf(subs={x:1})--> y + 2.0\n"
     ]
    }
   ],
   "source": [
    "# 首先定义x为一个符号，表示一个变量\n",
    "x = sympy.Symbol('x')\n",
    "fx = 2*x + 1\n",
    "print('type(fx)-->', type(fx))\n",
    "print('fx.evalf(subs={x:2})-->', fx.evalf(subs={x:2}))\n",
    "\n",
    "# 多元表达式\n",
    "x, y = sympy.symbols('x y')\n",
    "f = 2 * x + y\n",
    "# 以字典形式传入多个变量的值\n",
    "print('f.evalf(subs={x:1,y:2})-->', f.evalf(subs={x:1, y:2}))\n",
    "# 如果只传入一个变量的值, 则仅计算可以计算的部分\n",
    "print('f.evalf(subs={x:1})-->', f.evalf(subs={x:1}))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0dbe941-1165-4015-a8a0-9eb11c27f602",
   "metadata": {},
   "source": [
    "## 四、 解方程组\n",
    "\n",
    "使用sympy.solve函数解方程，该函数通常传入两个参数，第1个参数是方程的表达式（把方程所有的项移到等号的同一边形成的式子），第2个参数是方程中的未知数。函数的返回值是一个列表，代表方程的所有根（可能为复数根）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "f8f70c15-5b3f-4944-b7aa-b5515240bda5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sympy.solve(x-1, x)--> [1]\n",
      "sympy.solve(x ** 2 - 1, x) --> [-1, 1]\n",
      "sympy.solve(f, x) --> [-1]\n",
      "解方程组 --> {x: 2, y: -1}\n"
     ]
    }
   ],
   "source": [
    "# 解方程 x - 1 = 0\n",
    "print('sympy.solve(x-1, x)-->', sympy.solve(x-1, x))\n",
    "# 解方程 x^2 - 1 = 0\n",
    "print('sympy.solve(x ** 2 - 1, x) -->', sympy.solve(x**2-1, x))\n",
    "# 把函数式赋给一个变量\n",
    "f = x + 1\n",
    "print('sympy.solve(f, x) -->', sympy.solve(f, x))\n",
    "# 解方程组\n",
    "x,y = sympy.symbols('x y')\n",
    "print('解方程组 -->', sympy.solve([x+y-1, x-y-3], [x,y]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c26bf59f-23dc-479c-9dc9-80a4cf58deaf",
   "metadata": {},
   "source": [
    "### 4.1 计算求和式 \n",
    "\n",
    "$ \\sum_{n=1}^{100}2n $ 结果为 5050*2 = 10100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "79ebabe2-6442-4ea0-8fd7-e259e8cf4f6a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 10100$"
      ],
      "text/plain": [
       "10100"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n=sympy.Symbol('n')\n",
    "sympy.summation(2 * n, (n, 1, 100))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5afaa83d-d46a-4284-a166-9907a74a6409",
   "metadata": {},
   "source": [
    "### 4.2 解带有求和式的方程\n",
    "\n",
    "$ \\sum_{i=1}^{5}x + 10x = 15 $"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "bd174b92-12b8-47e3-87fc-4f81a42ec514",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = sympy.Symbol('x')\n",
    "i = sympy.Symbol('i', integer = True)\n",
    "f = sympy.summation(x, (i, 1, 5)) + 10 * x - 15\n",
    "sympy.solve(f, x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "492eabe7-ca9a-4329-bbb2-ea4a189a090a",
   "metadata": {},
   "source": [
    "## 五、微积分 \n",
    "\n",
    "### 5.1 求极限\n",
    "\n",
    "几个重要极限:\n",
    "\n",
    "- $ \\lim\\limits_{x \\to 0} \\frac{sinx}{x}=1$\n",
    "- $ \\lim\\limits_{x \\to 0}(1+x)^\\frac{1}{x}=e$\n",
    "- $ \\lim\\limits_{x \\to \\infty}(1+\\frac{1}{x})^x = e $"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "6598a990-2caa-4bda-abe8-09fd977b2334",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sin(x)/x --> 1\n",
      "\n",
      "(x + 1)**(1/x) --> E\n",
      "\n",
      "(1 + 1/x)**x --> E\n"
     ]
    }
   ],
   "source": [
    "x = sympy.Symbol('x')\n",
    "f1 = sympy.sin(x)/x\n",
    "print(f1, '-->', sympy.limit(f1, x, 0))\n",
    "print()\n",
    "f2 = (1+x)**(1/x)\n",
    "print(f2, '-->', sympy.limit(f2, x, 0))\n",
    "print()\n",
    "f3 = (1+1/x)**x\n",
    "print(f3, '-->', sympy.limit(f3, x, sympy.oo))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40c318c5-5d90-4987-8f15-fb9eeee92298",
   "metadata": {},
   "source": [
    "### 5.2 求导\n",
    "求导使用sympy.diff函数，传入2个参数：函数表达式和变量名，举例如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "13f3a57f-1f57-4129-a075-ae1a46b1abdb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x**2 + 2*x + 1 --> 2*x + 2\n",
      "sin(x) --> cos(x)\n",
      "x**2 + 2*x + y**3 --> 2*x + 2\n",
      "x**2 + 2*x + y**3 --> 3*y**2\n"
     ]
    }
   ],
   "source": [
    "x = sympy.Symbol('x')\n",
    "f = x ** 2 + 2 * x + 1\n",
    "print(f, '-->', sympy.diff(f, x))\n",
    "\n",
    "f2 = sympy.sin(x)\n",
    "print(f2, '-->', sympy.diff(f2, x))\n",
    "\n",
    "# 多元函数求偏导\n",
    "y = sympy.Symbol('y')\n",
    "f3 = x ** 2 + 2 * x + y ** 3\n",
    "print(f3, '-->', sympy.diff(f3, x))\n",
    "print(f3, '-->', sympy.diff(f3, y))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a105699-5301-41ed-b113-4fed928de3c1",
   "metadata": {},
   "source": [
    "### 5.3 求定积分\n",
    "\n",
    "使用sympy.integrate函数求定积分，其功能比较复杂，非常强大，下面仅仅举几个比较简单的例子。\n",
    "\n",
    "#### 5.3.1 简单的积分\n",
    "\n",
    "$ \\int_{0}^{1}2xdx $\n",
    "\n",
    "用牛顿-莱布尼兹公式可以立马口算出上面这个式子的结果是1，用代码计算如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "7a2e1d7e-427a-457a-9145-d5d1980b5264",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 1$"
      ],
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = sympy.Symbol('x')\n",
    "f = 2 * x\n",
    "# 传入函数表达式和积分变量、积分下限、上限\n",
    "sympy.integrate(f, (x,0,1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03184924-2933-4b02-bd9e-249adf58ec1a",
   "metadata": {},
   "source": [
    "#### 5.3.2 多重积分\n",
    "\n",
    "多重积分: $ \\int_{0}^{3}f(x)dx $\n",
    "\n",
    "其中: $ f(x) = \\int_{0}^{x}2xdx $\n",
    "\n",
    "通过口算可以求出`f(x)`: $ f(x) = \\int_{0}^{x}2xdx = 2^x $\n",
    "\n",
    "所以: $ \\int_{0}^{3}f(x)dx = \\int_{0}^{3}x^2dx = \\frac{1}{3}{x^3}_{\\mid 0}^{\\mid 3} = 9 $\n",
    "\n",
    "下面用代码来计算上述过程: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "6192e16f-562d-4c5c-8e40-e27ea579494a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 9$"
      ],
      "text/plain": [
       "9"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t,x = sympy.symbols('t x')\n",
    "f = 2 * t\n",
    "g = sympy.integrate(f, (t,0,x))\n",
    "sympy.integrate(g, (x,0,3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7853c36c-1c17-4929-a377-be8202aa7dd6",
   "metadata": {},
   "source": [
    "#### 5.3.4 求不定积分\n",
    "\n",
    "例如: $ \\int(e^x + 2x) dx $\n",
    "\n",
    "通过观察得知结果为: e^x + x^2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "25769042-12f5-4793-a90f-60f29e249c95",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle x^{2} + e^{x}$"
      ],
      "text/plain": [
       "x**2 + exp(x)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = sympy.Symbol('x')\n",
    "f = sympy.E ** x + 2 * x\n",
    "sympy.integrate(f, x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79bc63dd-f99e-44c6-8c89-884498dda131",
   "metadata": {},
   "source": [
    "## 六、 实战\n",
    "\n",
    "原文: https://www.zhihu.com/question/438689883"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c642efdb-d14f-4a83-96f8-2721730b4ef2",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
